// #include <Arduino.h>

// void setup() {
//   Serial.begin(9600);
//   Serial.println("\n-----------start-----------");
// }

// void loop() {

// }

#include <Arduino.h>
#include <WebServer.h>
#include<WiFi.h>

String getWifiList();

void webWifiList();
void notFound();
void submitWifi();
void webIndex();
void startApWeb();

IPAddress connectWifi(String networkName, String networkPwd);

int ledPin = 2;
int connectRetryNum = 0;


const char* apSsid = "ESP32";  // 设置AP的SSID
const char* apPwd = "12345678";  // 设置AP的密码


WebServer server(80);  // 创建WebServer对象，监听端口80

/**
 * 0 
 * 1 超时 重试过多次
 */
int connectErrorCode = 0;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  // IPAddress ip = connectWifi("WANSTU_2.4G", "wcy+929+");  

  startApWeb();
}

void loop(){
  server.handleClient();
}

void startApWeb() {
  IPAddress local_ip(192,168,4,1);  // 设置AP的IP地址
  IPAddress gateway(192,168,4,1);  // 设置AP的网关地址
  IPAddress subnet(255,255,255,0);  // 设置AP的子网掩码
  
  // WiFi.mode(WIFI_AP);
  WiFi.softAP(apSsid, apPwd);  // 配置ESP32进入软AP模式
  WiFi.softAPConfig(local_ip, gateway, subnet);  // 设置AP的静态IP配置
  
  Serial.print("\nAP IP address: ");
  Serial.println(WiFi.softAPIP());

  server.on("/", HTTP_GET, webIndex);  // 设置根目录路由的处理函数
  server.on("/index", HTTP_GET, webIndex);  // 设置根目录路由的处理函数
  server.on("/submitWifi", HTTP_POST, submitWifi);  // 设置配置WiFi路由的处理函数
  server.on("/webWifiList", HTTP_GET, webWifiList);  // 设置配置WiFi路由的处理函数
  server.onNotFound(notFound);  // 设置配置WiFi路由的处理函数


  server.begin();  // 启动Web服务器
  Serial.println("\nHTTP server started");

  getWifiList();

}

void webIndex() {
  String html = "<!DOCTYPE html><html lang='zh'><head> <meta charset='UTF-8'> <meta name='viewport' content='width=device-width, initial-scale=1.0'> <title>连接WIFI</title> <style> body { background: #f7f7f7; color: #111010; } #app { width: 260px; padding: 20px 10px; background: #d1d1d1; position: absolute; transform: translate(-50%, -50%); left: 50%; top: 50%; border-radius: 10px; } .form { display: flex; flex-flow: column; gap: 10px; } .form .input-item, .form .operate-item { display: flex; gap: 10px; justify-content: center; align-items: center; } .form .input-item .title { width: 68px; } input[type='text'] { border: none; padding: 5px; } input:focus-visible { outline: none; } </style></head><body> <div id='app'> <form action='/submitWifi' method='post'> <div class='form'> <div class='input-item'> <div class='title'>WIFI名称</div> <div class='content'> <input type='text' name='wifi_name' id='wifi_name'> </div> </div> <div class='input-item'> <div class='title'>WIFI密码</div> <div class='content'> <input type='text' name='wifi_pwd' id='wifi_pwd'> </div> </div> <div class='operate-item'> <div class='btn'> <input type='submit' value='提交' onClick='submit()'> </div> <!-- <div class='btn'> <input type='button' value='查看列表' onClick='jump2webList()'> </div> --> </div> </div> </form> <div class='wifi-list'> <!-- <iframe width='100%' src='./wifi-list.html'> </iframe> --> <iframe width='100%' src='/webWifiList'> </iframe> </div> </div></body><script> const wifiNameEl = document.getElementById('wifi_name'); const wifiPwdEl = document.getElementById('wifi_pwd'); wifiNameEl.focus(); function submit() { const wifiName = wifiNameEl.value; const wifiPwd = wifiPwdEl.value; if (!wifiName) { alert('请输入WIFI名称'); } if (!wifiPwd) { alert('请输入WIFI密码'); } const sendData = { wifi_name: wifiName, wifi_pwd: wifiPwd }; fetch('/submitWifi', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(sendData), }) .then((response) => response.json()) .then((data) => { console.log(data, 'submit Wifi Res'); }).catch(e => { console.log(e, 'submit Wifi Error'); }); } function jump2webList() { window.location.href = '/webWifiList' }</script></html>";
  server.send(200, "text/html", html);  // 发送HTML表单页面
}

void notFound() {
  String html = "404";
  server.send(404, "text/html", html);  // 发送HTML表单页面
}

void submitWifi() {  

  String wifi_name = server.arg("wifi_name");
  String wifi_pwd = server.arg("wifi_pwd");
  Serial.print("wifi_name:");
  Serial.println(wifi_name);
  Serial.print("wifi_pwd:");
  Serial.println(wifi_pwd);
  IPAddress ip = connectWifi(wifi_name, wifi_pwd);
  if(ip == IPAddress(0, 0, 0, 0)) {
    server.send(200, "text/html", "连接失败！");
  }
  server.send(200, "text/html", "连接成功！");

}


void webWifiList() {

  String html = getWifiList();

  server.send(200, "text/html", html);
}

String getWifiList() {
  int n = WiFi.scanNetworks();
  Serial.println("扫描wifi结束");
  if (n == 0) {
    Serial.println("未找到可用wifi！");
    return "";
  } else {
    Serial.print(n);
    Serial.println("可用wifi列表：");
    String body = "";
    body += String("<div class='wifi-list'>");
    for (int i = 0; i < n; ++i) {
      // Print SSID and RSSI for each network found
      body += String("<div class='wifi-item'><span class='number'>") + String(i + 1) + String("</span><span class='title'>") + String(WiFi.SSID(i)) + String("</span></div>");

      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println(WiFi.encryptionType(i));
      delay(20);
    }
    body += String("<div>");

    String html = String("<!DOCTYPE html><html lang='zh'> <head> <meta charset='UTF-8' /> <meta name='viewport' content='width=device-width, initial-scale=1.0' /> <title>WIFI列表</title> <style> body { background: #f7f7f7; color: #111010; } .wifi-box { display: flex; flex-flow: column; gap: 10px; } .wifi-item { display: flex; gap: 10px; } .number { width: 30px; text-align: center; background: #ccc; } </style> </head><body>")
      + body + String("</body><script></script></html>");

    Serial.println(html);
    return html;
  }
}


IPAddress connectWifi(String networkName, String networkPwd) {
  connectRetryNum = 0;
  WiFi.begin(networkName, networkPwd);
  while(WiFi.status()!=WL_CONNECTED){			//未连接上
    if(connectRetryNum > 5) {
      connectErrorCode = 1;
      break;
    }
    digitalWrite(ledPin, HIGH);
    connectRetryNum++;
    Serial.print("\n正在连接网络:【");
    Serial.print(networkName);
    Serial.println("】中...");

    delay(1000);
    digitalWrite(ledPin, LOW);
    delay(1000);
  }

  if(connectErrorCode != 0) {
    switch(connectErrorCode) {
      case 1:
        Serial.println("网络连接失败！");
        break;
    }
    
    for (int i = 3; i >= 0; i--) {
      digitalWrite(ledPin, HIGH);
      delay(1000);
      digitalWrite(ledPin, LOW);
      delay(500);
    }    
    return IPAddress(0, 0, 0, 0);
  }

  for (int i = 3; i >= 0; i--) {
    digitalWrite(ledPin, HIGH);
    delay(100);
    digitalWrite(ledPin, LOW);
    delay(500);
  }
  digitalWrite(ledPin, LOW);
  
  Serial.println("网络连接成功！");				//连接上
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  return WiFi.localIP();
}